namespace FIREFLYX {
    /**
     * 引擎全局入口对象
     */
    export class App {
        public static readonly version: string = "0.1.0";

        private static _lastTimeStamp: number = 0;
        private static _webgl2: WebGL2RenderingContext;
        private static _timeScale: number = 1;
        private static _time: number = 0;
        private static _deltaTime: number = 0;
        private static _unscaleTime: number = 0;
        private static _unscaleDeltaTime: number = 0;

        /** 源 HTMLCanvasElement 对象 */
        public static get canvasElement() { return ViewAspectManager.canvasElement; }
        /** WebGL2RenderingContext 对象 */
        public static get webgl2() { return this._webgl2; }
        /** 上一帧的时间增量 */
        public static get deltaTime() { return this._deltaTime; }
        /** 上一帧的时间增量 (不受 timeScale影响)*/
        public static get unscaleDeltaTime() { return this._unscaleDeltaTime; }
        /** 启动后累计时间 */
        public static get time() { return this._time; }
        /** 启动后累计时间 (不受 timeScale影响)*/
        public static get unscaleTime() { return this._unscaleTime; }

        public static init(canvasElement: HTMLCanvasElement, webglOpt?: WebGLContextAttributes): void
        public static init(divElement: HTMLDivElement, webglOpt?: WebGLContextAttributes): void
        public static init(element: HTMLCanvasElement | HTMLDivElement, webglOpt?: WebGLContextAttributes) {
            ViewAspectManager.init(element);
            this._webgl2 = this.canvasElement.getContext("webgl2", webglOpt) || {} as any;

            //各系统初始化
            WebglCapability.init(this._webgl2);
            Browser.init();
            SceneManager.init(this._webgl2);
            InputManager.init();
            AssetManager.init();
            Graphics.init();

            //启动 update流
            requestAnimationFrame(this.loop);
        }

        private static loop(timeStamp: number) {
            App._unscaleDeltaTime = (timeStamp - App._lastTimeStamp) * 0.001;
            App._unscaleTime += App._unscaleDeltaTime;

            App._deltaTime = App._unscaleDeltaTime * App._timeScale;
            App._time += App._deltaTime;

            App._lastTimeStamp = timeStamp;
            App.update(App._deltaTime);
            //loop
            requestAnimationFrame(App.loop);
        }

        private static update(dt: number) {
            //派送事件
            const gem = GlobalEventManager.Instance;
            if (gem.listenerCount("appLoopStart") > 0) GlobalEventManager.Instance.dispatchEvent("appLoopStart", dt);
            //
            ViewAspectManager.update();
            //场景 update
            SceneManager.update(dt);
            //
            if (gem.listenerCount("appLoopEnd") > 0) GlobalEventManager.Instance.dispatchEvent("appLoopEnd", dt);
        }
    }
}